package hotel.controller.room;

import javafx.fxml.FXML;

import javafx.scene.control.Button;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;

import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.Room;
import hotel.modal.RoomChange;
import hotel.modal.RoomRent;
import hotel.modal.RoomType;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;

import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.ComboBox;

public class RentChangeController {
	@FXML
	private Label titleLabel;
	@FXML
	private ComboBox<Room> roomCb;
	@FXML
	private ComboBox<RoomType> roomTypeCb;
	@FXML
    private TextField commentField;
	@FXML
	private Button btnOk;
	@FXML
	private Button btnCancel;
	
	protected RoomRent roomRent;
	protected Room preRoom;

	@FXML
	public void initialize() {
		initComponent();
		loadData();
	}
	
	private void loadData() {
		List<RoomType> list = HotelDao.getAllRoomType();
		ObservableList<RoomType> roomTypeItems = roomTypeCb.getItems();
		roomTypeItems.addAll(list);
		if(list.size() > 0) roomTypeCb.getSelectionModel().select(0);
	}
	
	
	private int findRoomTypeCbIndex(RoomType rt) {
		if(rt == null) return 0;
		ObservableList<RoomType> items = roomTypeCb.getItems();
		RoomType t = null;
		for(int i = 0; i < items.size(); i++) {
			t = items.get(i);
			if(t!= null && rt.getTypeId() == t.getTypeId()) return i;
		}
		return 0;
	}
	
	private List<Room> runRoomCbFilter(List<Room> list) {
		Iterator<Room> iter = list.iterator();
		Room room = null;
		while(iter.hasNext()) {
			room = iter.next();
			if(room.getStatus() > 2) { 	// 状态为可供或者预定的房间才符合要求
				iter.remove();			// 将不符合要求的房间移除
			}
		}
		return list;
	}
	
	public RoomRent getRoomRent() {
		return roomRent;
	}

	public void setRoomRent(RoomRent roomRent) {
		this.roomRent = roomRent;
		if(roomRent != null) {
			preRoom = HotelDao.getRoom(roomRent.getRoomNo());
			if(preRoom == null) return;
			int index = findRoomTypeCbIndex(preRoom);
			roomTypeCb.getSelectionModel().select(index);
		}
	}

	private boolean dealData() {
		if(roomRent == null || preRoom == null) return false;
		String preRoomNo = preRoom.getRoomNo();
		Room room = roomCb.getSelectionModel().getSelectedItem();
		preRoom.setStatus(4);
		room.setStatus(3);
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		RoomChange roomChange = new RoomChange();
		roomChange.setPreOrderId(roomRent.getPreOrderId());
		roomChange.setPreRoomNo(preRoomNo);
		roomChange.setNowRoomNo(room.getRoomNo());
		roomChange.setChangeTime(now.format(formatter));
		roomChange.setComment(commentField.getText());
		roomRent.setRoomNo(room.getRoomNo());
			roomRent.setModified(true);
		if(HotelDao.add(roomChange) && HotelDao.update(room) && HotelDao.update(preRoom)) {
			return true;
		}else
			return false;
	}

	// Event Listener on Button[#btnOk].onAction
	@FXML
	public void onBtnOkAction(ActionEvent event) {
		hideWindow();
		if(dealData()) {
			MsgBox.showInformationDialog("提示", null, "已经成功换房！");
		}else {
			MsgBox.showErrorDialog("错误", null, "换房失败！");
			roomRent.setModified(false);
		}
		closeWindow();
	}
	
	// Event Listener on Button[#btnCancel].onAction
	@FXML
	public void onBtnCancelAction(ActionEvent event) {
		roomRent.setModified(false);
		closeWindow();
	}
	
	private void hideWindow() {
		Stage stage = (Stage)btnCancel.getScene().getWindow();
		stage.hide();
	}
	
	private void closeWindow() {
		Stage stage = (Stage)btnCancel.getScene().getWindow();
		stage.close();
	}
	
	private void initComponent() {
		roomTypeCb.setCellFactory(new Callback<ListView<RoomType>, ListCell<RoomType>>() { // 下拉列表显示
			@Override
			public ListCell<RoomType> call(ListView<RoomType> p) {
				ListCell<RoomType> cell = new ListCell<RoomType>() {
					@Override
					protected void updateItem(RoomType item, boolean empty) {
						super.updateItem(item, empty);
						if (empty) {
							setText("");
						} else {
							if (item.isHourRoom()) setText(item.getTypeName() + "(钟点房)");
							else setText(item.getTypeName());
						}
					}
				};
				return cell;
			}
		});

		roomTypeCb.setButtonCell(new ListCell<RoomType>() {
			@Override
			protected void updateItem(RoomType item, boolean empty) {
				super.updateItem(item, empty);
				if (empty) {
					setText("");
				} else {
					if (item.isHourRoom())
						setText(item.getTypeName() + "(钟点房)");
					else
						setText(item.getTypeName());
				}
			}
		});

		roomTypeCb.valueProperty().addListener(new ChangeListener<RoomType>() { // 房间类型ComBobox监听
			@Override
			public void changed(ObservableValue<? extends RoomType> observable, RoomType oldValue, RoomType newValue) {
				List<Room> rList = runRoomCbFilter(HotelDao.getRoomList(newValue)); // 从数据库拉取房间信息
				ObservableList<Room> obList = FXCollections.observableArrayList(rList);
				roomCb.setItems(obList);
				if (obList.size() > 0)
					roomCb.getSelectionModel().select(0);
			}
		});

		roomCb.setCellFactory(new Callback<ListView<Room>, ListCell<Room>>() { // 下拉列表显示
			@Override
			public ListCell<Room> call(ListView<Room> p) {
				ListCell<Room> cell = new ListCell<Room>() {
					@Override
					protected void updateItem(Room item, boolean empty) {
						super.updateItem(item, empty);
						if (empty) {
							setText("");
						} else {
							setText(item.getRoomNo());
						}
					}
				};
				return cell;
			}
		});

		roomCb.setButtonCell(new ListCell<Room>() {
			@Override
			protected void updateItem(Room item, boolean empty) {
				super.updateItem(item, empty);
				if (empty) {
					setText("");
				} else {
					setText(item.getRoomNo());
				}
			}
		});

		roomCb.valueProperty().addListener(new ChangeListener<Room>() {
			@Override
			public void changed(ObservableValue<? extends Room> observable, Room oldValue, Room newValue) {
				if (newValue == null) {
					btnOk.setDisable(true);
				} else {
					if (btnOk.isDisable())
						btnOk.setDisable(false);
				}
			}
		});
	}
	
}
